/**
  RTC DS3231 simple driver for ATMEGA
  Copyright (C) 2015 Rodrigo Garcia

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>. 

See rtcDS3231.h for reference
 */

#include "rtcDS3231.h"

//struct _rtc_time;

uint8_t bcd2dec(uint8_t b)
{
  return ((b/16 * 10) + (b % 16));
}

uint8_t dec2bcd(uint8_t d)
{
  return ((d/10 * 16) + (d % 10));
}

void DS3231_init_slow(void)
{
  i2c_init();
}

// sets the time of the RTC
char DS3231_set_time(struct RTC_time time)
{
  if(!i2c_start())
    return 1;// no se pudo enviar START

  // envia SLA+W (dir del esclavo + W)
  if(i2c_write((DS3231_SLAVE_ADDRESS<<1) | DS3231_WRITE) == 1)
    return 2; // error en la transmision

  // carga el puntero del RTC para comenzar a escribir desde el registro de los segundos
  if(i2c_write(DS3231_SECS_REG) == 1)
    return 3;

  // ---- Comienza a escribir en los registros del RTC ----
  if(i2c_write(dec2bcd(time.sec)) == 1) // segundos
    return 4;
  if(i2c_write(dec2bcd(time.min)) == 1)  // minutos
    return 5;
  if(i2c_write(dec2bcd(time.hour)) == 1)  // horas
    return 6;
  if(i2c_write(dec2bcd(time.wday)) == 1)  // dias de la semana
    return 7;
  if(i2c_write(dec2bcd(time.mday)) == 1) // dias del mes
    return 8;
  if(i2c_write(dec2bcd(time.mon)) == 1) // mes
    return 9;
  if(i2c_write(dec2bcd(time.year)) == 1) // anyo
    return 10;
  // --------
  i2c_stop(); // termina la escritura
  return 0;
}


//gets the time reading all the tiem related DS3231 registers
char DS3231_get_time(struct RTC_time* time)
{
  if(!i2c_start())
    return 1;// no se pudo enviar START

  // envia SLA+W (dir del esclavo + W) 
  if(i2c_write((DS3231_SLAVE_ADDRESS<<1) | DS3231_WRITE) == 1)
    return 2; // error en la transmision

  // carga el puntero del RTC  para comenzar a leer desde el registro de los segundos
  if(i2c_write(DS3231_SECS_REG) == 1)
    return 3;
  
  // ---- Comienza la lectura de los registros del RTC ----
  if(!i2c_start()) // condicion START repetida
    return 4;
  // envia SLA+R (dir del esclavo + R) 
  if(i2c_write((DS3231_SLAVE_ADDRESS<<1) | DS3231_READ) == 1)
    return 5; // error en la transmision
  
  time->sec = bcd2dec(i2c_read(DS3231_ACK)); // segundos
  time->min = bcd2dec(i2c_read(DS3231_ACK)); // minutos
  time->hour = bcd2dec(i2c_read(DS3231_ACK)); // horas
  time->wday = bcd2dec(i2c_read(DS3231_ACK)); // dias de la semana
  time->mday = bcd2dec(i2c_read(DS3231_ACK)); // dia del mes
  time->mon = bcd2dec(i2c_read(DS3231_ACK)); // mes
  time->year = bcd2dec(i2c_read(DS3231_NACK)); // anyo (termina la lectura)

  i2c_stop(); // termina la transmision
  return 0;
  // --------
  
}

